home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 3 of 3 / CHAPTE21 / AVICOPY.C next >
C/C++ Source or Header  |  1996-04-29  |  17KB  |  597 lines

  1.  
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "AviCopy.h"
  5. #include <vfw.h>
  6.  
  7.  
  8. #if defined (WIN32)
  9.     #define IS_WIN32 TRUE
  10. #else
  11.     #define IS_WIN32 FALSE
  12. #endif
  13.  
  14. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  15. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  16. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  17.  
  18.  
  19. HINSTANCE hInst;   // current instance
  20.  
  21. LPCTSTR lpszAppName = "MyApp";
  22. LPCTSTR lpszTitle   = "My Application"; 
  23.  
  24. // the rest of the stuff
  25. //......................
  26.  
  27. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  28.  
  29.  
  30. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  31.                       LPTSTR lpCmdLine, int nCmdShow)
  32. {
  33.    MSG      msg;
  34.    HWND     hWnd; 
  35.    WNDCLASS wc;
  36.  
  37.    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  38.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  39.    wc.cbClsExtra    = 0;                      
  40.    wc.cbWndExtra    = 0;                      
  41.    wc.hInstance     = hInstance;              
  42.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  43.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  44.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  45.    wc.lpszMenuName  = lpszAppName;              
  46.    wc.lpszClassName = lpszAppName;              
  47.  
  48.    if ( IS_WIN95 )
  49.    {
  50.       if ( !RegisterWin95( &wc ) )
  51.          return( FALSE );
  52.    }
  53.    else if ( !RegisterClass( &wc ) )
  54.       return( FALSE );
  55.  
  56.    hInst = hInstance; 
  57.  
  58.    hWnd = CreateWindow( lpszAppName, 
  59.                         lpszTitle,    
  60.                         WS_OVERLAPPEDWINDOW, 
  61.                         CW_USEDEFAULT, 0, 
  62.                         CW_USEDEFAULT, 0,  
  63.                         NULL,              
  64.                         NULL,              
  65.                         hInstance,         
  66.                         NULL               
  67.                       );
  68.  
  69.    if ( !hWnd ) 
  70.       return( FALSE );
  71.  
  72.    ShowWindow( hWnd, nCmdShow ); 
  73.    UpdateWindow( hWnd );         
  74.  
  75.    while( GetMessage( &msg, NULL, 0, 0) )   
  76.    {
  77.       TranslateMessage( &msg ); 
  78.       DispatchMessage( &msg );  
  79.    }
  80.  
  81.    return( msg.wParam ); 
  82. }
  83.  
  84.  
  85. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  86. {
  87.     WNDCLASSEX wcex;
  88.  
  89.    wcex.style         = lpwc->style;
  90.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  91.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  92.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  93.    wcex.hInstance     = lpwc->hInstance;
  94.    wcex.hIcon         = lpwc->hIcon;
  95.    wcex.hCursor       = lpwc->hCursor;
  96.    wcex.hbrBackground = lpwc->hbrBackground;
  97.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  98.    wcex.lpszClassName = lpwc->lpszClassName;
  99.  
  100.    // Added elements for Windows 95.
  101.    //...............................
  102.    wcex.cbSize = sizeof(WNDCLASSEX);
  103.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  104.                             IMAGE_ICON, 16, 16,
  105.                             LR_DEFAULTCOLOR );
  106.             
  107.    return RegisterClassEx( &wcex );
  108. }
  109.  
  110.  
  111.  
  112. LRESULT CALLBACK About( HWND hDlg,           
  113.                         UINT message,        
  114.                         WPARAM wParam,       
  115.                         LPARAM lParam)
  116. {
  117.    switch (message) 
  118.    {
  119.        case WM_INITDIALOG: 
  120.                return (TRUE);
  121.  
  122.        case WM_COMMAND:                              
  123.                if (   LOWORD(wParam) == IDOK         
  124.                    || LOWORD(wParam) == IDCANCEL)    
  125.                {
  126.                        EndDialog(hDlg, TRUE);        
  127.                        return (TRUE);
  128.                }
  129.                break;
  130.    }
  131.  
  132.    return (FALSE); 
  133. }
  134.  
  135.  
  136. #define MSG_LEN          1024
  137.  
  138. char       msg[MSG_LEN+1];
  139. int        nTabStop = 100;
  140. HWND       hListBox = NULL;
  141.  
  142.  
  143. VOID CopyAVI(HWND hWnd, UINT uOption);
  144. VOID CopyStream(HWND hWnd, PAVISTREAM pAviStream, AVISTREAMINFO* pStreamInfo);
  145. VOID DisplayAviInfo(AVIFILEINFO* pFileInfo);
  146.  
  147.  
  148. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  149. {
  150.    switch( uMsg )
  151.    {
  152.       case WM_CREATE :
  153.               // initialize the AVI library DLL
  154.               //...............................
  155.  
  156.               AVIFileInit();
  157.  
  158.               // Create ListBox
  159.               //...............
  160.  
  161.  
  162.               hListBox = CreateWindow( "LISTBOX", "",    
  163.                                        WS_CHILD | LBS_NOTIFY | 
  164.                                        WS_VSCROLL | WS_BORDER | 
  165.                                        WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
  166.                                        LBS_USETABSTOPS, 
  167.                                        0, 0, 
  168.                                        0, 0,  
  169.                                        hWnd,              
  170.                                        (HMENU)101,              
  171.                                        hInst,         
  172.                                        NULL );
  173.  
  174.               SendMessage(hListBox, LB_SETTABSTOPS, 1, (LPARAM)&nTabStop);
  175.               break;
  176.  
  177.       case WM_SIZE :
  178.               MoveWindow( hListBox, 0, 0, 
  179.                           LOWORD( lParam ), 
  180.                           HIWORD( lParam ), TRUE );
  181.               break;
  182.  
  183.       case WM_COMMAND :
  184.               switch( LOWORD(wParam) )
  185.               {
  186.                  case IDM_COPYVIDEO:
  187.                  case IDM_COPYALL  :
  188.  
  189.                         {
  190.                            SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  191.                            CopyAVI(hWnd, LOWORD(wParam) );
  192.                         }
  193.                         break;
  194.  
  195.                  case IDM_ABOUT :
  196.                         DialogBox( hInst, "AboutBox", hWnd, About );
  197.                         break;
  198.  
  199.                  case IDM_EXIT :
  200.                         DestroyWindow( hWnd );
  201.                         break;
  202.               }
  203.               break;
  204.  
  205.       case WM_DESTROY :
  206.               
  207.               // release the AVI library DLL
  208.               //............................
  209.  
  210.               AVIFileExit();
  211.  
  212.               PostQuitMessage(0);
  213.               break;
  214.  
  215.       default :
  216.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  217.    }
  218.  
  219.    return(0L);               
  220. }
  221.  
  222. /*****************************************************************************
  223. *  Global variables
  224. *
  225. *
  226. *
  227. ******************************************************************************/
  228.  
  229. HRESULT       rc;
  230.  
  231. LPCTSTR       lpszInputFilename = "small.avi";
  232.  
  233. PAVIFILE      pAviIn            = NULL;
  234. PAVIFILE      pAviOut           = NULL;
  235. PAVISTREAM    pAviTmpStream     = NULL;
  236.  
  237. LONG          nAviStreams       = 0L; // number of pAviStreams[];
  238. PAVISTREAM    pAviStream[2]     = { NULL, NULL };
  239. AVICOMPRESSOPTIONS   Options[2];
  240. LPAVICOMPRESSOPTIONS pOptions[2];
  241.  
  242. AVIFILEINFO   pFileInfo;
  243. AVISTREAMINFO pStreamInfo;
  244.  
  245. /*****************************************************************************
  246. *  CopyAVI
  247. *
  248. *
  249. *
  250. ******************************************************************************/
  251.  
  252. VOID CopyAVI(HWND hWnd, UINT uOption)
  253. {
  254.    LONG i; 
  255.  
  256.    // open input AVI file
  257.    //....................
  258.  
  259.    rc = AVIFileOpen(&pAviIn, lpszInputFilename, OF_READ, NULL);
  260.  
  261.    if (rc) // if error
  262.    {
  263.        MessageBox(hWnd, "Error opening AVI file.",
  264.                   NULL, MB_OK);
  265.        return;
  266.    }
  267.  
  268.    // open output file
  269.    //.................
  270.  
  271.    remove("AviCopy.avi"); // destroy previous version (if any)
  272.  
  273.    rc = AVIFileOpen(&pAviOut, "AviCopy.avi", OF_CREATE|OF_WRITE, NULL);
  274.  
  275.    if (rc)
  276.    {
  277.        MessageBox(hWnd, "Error creating new AVI file.",
  278.                   NULL, MB_OK);
  279.        return;
  280.    }
  281.  
  282.    // get input AVI file info
  283.    //........................
  284.  
  285.    rc = AVIFileInfo(pAviIn, &pFileInfo, sizeof(AVIFILEINFO));
  286.    
  287.    DisplayAviInfo(&pFileInfo);
  288.    UpdateWindow(hWnd);
  289.  
  290.    // write optional header data
  291.    //...........................
  292.  
  293.    sprintf(msg, "Copy of %s. Created by AVICOPY.", lpszInputFilename);
  294.  
  295.    AVIFileWriteData(pAviOut, mmioStringToFOURCC("Copy", 0),
  296.                     (LPVOID)msg, strlen(msg)+1);
  297.  
  298.    // get AVI streams
  299.    //................
  300.  
  301.    if (uOption == IDM_COPYVIDEO)  // copy only video
  302.    {
  303.        rc = AVIStreamOpenFromFile(&pAviTmpStream, lpszInputFilename,
  304.                                   streamtypeVIDEO, 0, OF_READ, NULL);
  305.  
  306.        if (!rc)
  307.            pAviStream[nAviStreams++] = pAviTmpStream;
  308.    }
  309.    else
  310.    {
  311.        for (i = 0; i < (LONG)pFileInfo.dwStreams; i++) 
  312.        { 
  313.           rc = AVIFileGetStream(pAviIn, &pAviTmpStream, 0L, i);
  314.        
  315.           if (rc) 
  316.             continue;
  317.  
  318.           rc = AVIStreamInfo(pAviTmpStream, &pStreamInfo, sizeof(AVISTREAMINFO)); 
  319.  
  320.           if (rc)
  321.               continue;
  322.  
  323.           if (pStreamInfo.fccType == streamtypeVIDEO)
  324.               pAviStream[nAviStreams++] = pAviTmpStream;
  325.           else if (pStreamInfo.fccType == streamtypeAUDIO &&
  326.                    uOption == IDM_COPYALL )
  327.               pAviStream[nAviStreams++] = pAviTmpStream;
  328.           else
  329.               AVIStreamRelease(pAviTmpStream);
  330.       }
  331.    }
  332.    
  333.    // get save (compression) options
  334.    //...............................
  335.  
  336.    for (i = 0; i < nAviStreams; i++)
  337.    {
  338.       // AVISaveOptions takes an array of pointers to our 
  339.       // compression options (cleared)
  340.  
  341.       pOptions[i] = &Options[i];
  342.       memset(pOptions[i], 0, sizeof(AVICOMPRESSOPTIONS));
  343.    }
  344.  
  345.    AVISaveOptions(hWnd,
  346.                   ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE | 
  347.                   ICMF_CHOOSE_PREVIEW,
  348.                   nAviStreams,
  349.                   pAviStream,
  350.                   pOptions);
  351.    
  352.    // copy streams
  353.    //.............
  354.    
  355.    for (i = 0; i < nAviStreams; i++)
  356.    {
  357.       pAviTmpStream = NULL;
  358.  
  359.       rc = AVIMakeCompressedStream(&pAviTmpStream, 
  360.                                    pAviStream[i],
  361.                                    pOptions[i],
  362.                                    NULL);
  363.  
  364.       // check if it can be compressed
  365.       // this can happen if no compression was requested
  366.       //................................................
  367.  
  368.       if (rc == AVIERR_OK)
  369.       {   // use compressed stream
  370.           AVIStreamInfo(pAviTmpStream, &pStreamInfo, sizeof(AVISTREAMINFO));
  371.           CopyStream(hWnd, pAviTmpStream, &pStreamInfo);
  372.  
  373.           if (pAviTmpStream)
  374.               AVIStreamRelease(pAviTmpStream);
  375.       }
  376.       else
  377.       {   // use original stream
  378.           AVIStreamInfo(pAviStream[i], &pStreamInfo, sizeof(AVISTREAMINFO));
  379.           CopyStream(hWnd, pAviStream[i], &pStreamInfo);
  380.       }
  381.    }  
  382.  
  383.    AVISaveOptionsFree(nAviStreams, pOptions);
  384.    
  385.    // close AVI files
  386.    //................
  387.  
  388.    AVIFileRelease(pAviIn); 
  389.    AVIFileRelease(pAviOut);
  390. }
  391.  
  392. /*****************************************************************************
  393. *  CopyStream
  394. *
  395. *
  396. *
  397. ******************************************************************************/
  398.  
  399. VOID CopyStream(HWND hWnd, PAVISTREAM pAviStream, AVISTREAMINFO* pStreamInfo)
  400. {
  401.     LONG             nFormatSize;
  402.     LONG             nSampleSize;
  403.     LONG             nStreamSize;
  404.      
  405.     LONG             nSamplePosition;
  406.     LONG             nSamplesRead;
  407.     PAVISTREAM       pNewStream;
  408.     LPVOID           pBuffer     = NULL;
  409.     LONG             nBufferSize = 32767L;
  410.  
  411.     // alloc buffer
  412.     //.............
  413.     
  414.     pBuffer = HeapAlloc( GetProcessHeap(),                         
  415.                           HEAP_ZERO_MEMORY,                         
  416.                           nBufferSize);
  417.     
  418.     // read stream format
  419.     //...................
  420.  
  421.     rc = AVIStreamFormatSize(pAviStream, 0, &nFormatSize);
  422.  
  423.     if (!rc && nFormatSize > nBufferSize)
  424.     {
  425.         pBuffer = HeapReAlloc( GetProcessHeap(),
  426.                                HEAP_ZERO_MEMORY,
  427.                                pBuffer,
  428.                                nFormatSize);
  429.  
  430.        if (pBuffer)
  431.            nBufferSize = nFormatSize;
  432.     }
  433.  
  434.     rc = AVIStreamReadFormat(pAviStream, 0, pBuffer, &nFormatSize);
  435.  
  436.     // create new video stream
  437.     //........................
  438.  
  439.     rc = AVIFileCreateStream(pAviOut, &pNewStream, pStreamInfo); 
  440.     
  441.     if (rc) 
  442.     {
  443.         MessageBox(NULL, "Error creating new video stream.", NULL, MB_OK);
  444.         return; 
  445.     } 
  446.  
  447.     // Set format of new stream
  448.     //......................... 
  449.  
  450.     rc = AVIStreamSetFormat(pNewStream, 0, pBuffer, nFormatSize); 
  451.  
  452.     if (rc) 
  453.     { 
  454.         MessageBox(NULL, "Error setting stream format.", NULL, MB_OK);
  455.         AVIStreamRelease(pNewStream); 
  456.         return; 
  457.     } 
  458.  
  459.     // allocate buffer, instruct AVIStreamRead to
  460.     // suggest buffer size to use
  461.     //...........................................
  462.  
  463.     rc = AVIStreamRead(pAviStream,
  464.                        AVIStreamStart(pAviStream), 
  465.                        AVISTREAMREAD_CONVENIENT,
  466.                        NULL, 0L, &nStreamSize, NULL);
  467.     
  468.     // check if we must enlarge the buffer
  469.     
  470.     if (!rc && nStreamSize > nBufferSize)
  471.     {
  472.         pBuffer = HeapReAlloc( GetProcessHeap(),
  473.                                HEAP_ZERO_MEMORY,
  474.                                pBuffer,
  475.                                nStreamSize);
  476.  
  477.        if (pBuffer)
  478.            nBufferSize = nStreamSize;
  479.    }
  480.  
  481.    // Read the stream data
  482.    //.....................
  483.    
  484.    for (nSamplePosition = AVIStreamStart(pAviStream); 
  485.         pBuffer && nSamplePosition < AVIStreamEnd(pAviStream); ) 
  486.    { 
  487.       AVIStreamSampleSize(pAviStream, nSamplePosition, &nSampleSize);
  488.       
  489.       rc = AVIStreamRead(pAviStream, nSamplePosition, 
  490.                          (nBufferSize / nSampleSize),  // est. sample to read
  491.                          pBuffer, nBufferSize, 
  492.                          &nStreamSize, &nSamplesRead);
  493.  
  494.       rc = AVIStreamWrite(pNewStream, nSamplePosition, nSamplesRead, 
  495.                           pBuffer, nStreamSize, 
  496.                           AVIIF_KEYFRAME, &nSamplesRead, &nStreamSize); 
  497.  
  498.       nSamplePosition += nSamplesRead;
  499.  
  500.       // display status
  501.  
  502.       sprintf(msg, "Copying stream: <%s>, %ld of %ld samples written.",
  503.               pStreamInfo->szName, 
  504.               nSamplePosition, AVIStreamEnd(pAviStream));
  505.       SetWindowText(hWnd, msg);
  506.    }
  507.     
  508.    HeapFree(GetProcessHeap(), 0, pBuffer); 
  509.  
  510.    // Close the stream and file
  511.    //.......................... 
  512.     
  513.    AVIStreamRelease(pNewStream);
  514.    
  515.    SetWindowText(hWnd, lpszTitle); 
  516. }
  517.  
  518. /*****************************************************************************
  519. *  DisplayAviInfo
  520. *
  521. *
  522. *
  523. ******************************************************************************/
  524.  
  525. #define Display(msg)    SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg)
  526.  
  527. VOID DisplayAviInfo(AVIFILEINFO* pFileInfo)
  528. {
  529.    SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  530.  
  531.    sprintf(msg, "Max bytes/sec:\t %ld", pFileInfo->dwMaxBytesPerSec);
  532.    Display(msg);
  533.  
  534.    sprintf(msg, "Flags (has index):\t %s", 
  535.            (pFileInfo->dwFlags & AVIFILEINFO_HASINDEX ? "Yes" : "No") );
  536.    Display(msg);
  537.  
  538.    sprintf(msg, "Flags (must use index):\t %s",
  539.            (pFileInfo->dwFlags & AVIFILEINFO_MUSTUSEINDEX ? "Yes" : "No") );
  540.    Display(msg);
  541.  
  542.    sprintf(msg, "Flags (is interleaved):\t %s",
  543.            (pFileInfo->dwFlags & AVIFILEINFO_ISINTERLEAVED ? "Yes" : "No") );
  544.    Display(msg);
  545.  
  546.    sprintf(msg, "Flags (was capture file):\t %s",
  547.            (pFileInfo->dwFlags & AVIFILEINFO_WASCAPTUREFILE ? "Yes" : "No") );
  548.    Display(msg);
  549.  
  550.    sprintf(msg, "Flags (copyrighted):\t %s",
  551.            (pFileInfo->dwFlags & AVIFILEINFO_COPYRIGHTED ? "Yes" : "No") );
  552.    Display(msg);
  553.  
  554.    sprintf(msg, "Caps (can read):\t %s",
  555.            (pFileInfo->dwCaps & AVIFILECAPS_CANREAD ? "Yes" : "No") );
  556.    Display(msg);
  557.  
  558.    sprintf(msg, "Caps (can write):\t %s",
  559.            (pFileInfo->dwCaps & AVIFILECAPS_CANWRITE ? "Yes" : "No") );
  560.    Display(msg);
  561.  
  562.    sprintf(msg, "Caps (all key frames):\t %s",
  563.            (pFileInfo->dwCaps & AVIFILECAPS_ALLKEYFRAMES ? "Yes" : "No") );
  564.    Display(msg);
  565.  
  566.    sprintf(msg, "Caps (compressed):\t %s",  // read carefully (it's backwards)
  567.            (pFileInfo->dwCaps & AVIFILECAPS_NOCOMPRESSION ? "No" : "Yes") );
  568.    Display(msg);
  569.  
  570.    sprintf(msg, "Number of streams:\t %ld", pFileInfo->dwStreams);
  571.    Display(msg);
  572.  
  573.    sprintf(msg, "Sugg. buffer size:\t %ld", pFileInfo->dwSuggestedBufferSize);
  574.    Display(msg);
  575.  
  576.    sprintf(msg, "Width:\t %ld", pFileInfo->dwWidth);
  577.    Display(msg);
  578.  
  579.    sprintf(msg, "Height:\t %ld", pFileInfo->dwHeight);
  580.    Display(msg);
  581.  
  582.    sprintf(msg, "Scale:\t %ld", pFileInfo->dwScale);
  583.    Display(msg);
  584.  
  585.    sprintf(msg, "Rate:\t %ld", pFileInfo->dwRate);
  586.    Display(msg);
  587.  
  588.    sprintf(msg, "Length:\t %ld", pFileInfo->dwLength);
  589.    Display(msg);
  590.  
  591.    sprintf(msg, "Edit count:\t %ld", pFileInfo->dwEditCount);
  592.    Display(msg);
  593.  
  594.    sprintf(msg, "File type:\t %s", pFileInfo->szFileType);
  595.    Display(msg);
  596. }
  597.